﻿using WCS.WebRequest;
using Newtonsoft.Json;
using Service;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WCS;
using WCS.Controls.RunLog;
using WCS.Entity;
using WCS.Utils;
using WcsTask.DevCommTaks;
using Newtonsoft.Json.Serialization;
using Sunny.UI.Win32;
using System.Xml;

namespace Client
{
    public class ClientSocket
    {
        private ClientSocket() { }

        private static readonly ClientSocket client = new ClientSocket();

        public static ClientSocket _clientSocket
        {
            get
            {
                return client;
            }
        }

        /// <summary>
        /// 数据库连接对象
        /// </summary>
        static SqlSugarDapper _SqlSugarDapper = SqlSugarDapper.GetDbContext();

        String IP = "127.0.0.1";
        int port = 56001;

        /// <summary>
        /// 将对象转换为byte数组
        /// </summary>
        /// <param name="obj">被转换对象</param>
        /// <returns>转换后byte数组</returns>
        //public static byte[] Object2Bytes(object obj)
        //{
        //    byte[] buff;
        //    using (MemoryStream ms = new MemoryStream())
        //    {
        //        IFormatter iFormatter = new BinaryFormatter();
        //        iFormatter.Serialize(ms, obj);
        //        buff = ms.GetBuffer();
        //    }
        //    return buff;
        //}

        /// <summary>
        /// 将对象转换为byte数组
        /// </summary>
        /// <param name="obj">被转换对象</param>
        /// <returns>转换后byte数组</returns>
        public byte[] ObjectToByteArray(Object obj)
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (var ms = new MemoryStream())
            {
                bf.Serialize(ms, obj);
                return ms.ToArray();
            }
        }

        public T ByteArrayToObject<T>(byte[] arrBytes)
        {
            using (var memStream = new MemoryStream())
            {
                var binForm = new BinaryFormatter();
                memStream.Write(arrBytes, 0, arrBytes.Length);
                memStream.Seek(0, SeekOrigin.Begin);
                var obj = binForm.Deserialize(memStream);

                return ConvertObject<T>(obj);
            }
        }

        string tou = "02020202";

        string wei = "FFFFFFFF";

        /// <summary>
        /// 发送数据
        /// </summary>
        public byte[] SendData(Data n)
        {
            byte[] b = new byte[43];

            var bb = Encoding.ASCII.GetBytes("1111");
            var ts = BitConverter.GetBytes(1111);
            var t = BitConverter.GetBytes(Convert.ToInt32(tou, 16));

            //t.CopyTo(b, 0);
            //Encoding.ASCII.GetBytes(n.BBBBBBBBBB).CopyTo(b, 4);
            //Encoding.ASCII.GetBytes(n.Name).CopyTo(b, 8);
            //Encoding.ASCII.GetBytes(n.TaskCode).CopyTo(b, 15);
            //Encoding.ASCII.GetBytes(n.ip).CopyTo(b, 19);


            var w = BitConverter.GetBytes(Convert.ToInt32(wei, 16));
            w.CopyTo(b, 39);

            return b;
        }

        /// <summary>
        /// 将object对象转换为实体对象
        /// </summary>
        /// <typeparam name="T">实体对象类名</typeparam>
        /// <param name="asObject">object对象</param>
        /// <returns></returns>
        private T ConvertObject<T>(object asObject)
        {
            //创建实体对象实例
            var t = Activator.CreateInstance<T>();
            if (asObject != null)
            {
                Type type = asObject.GetType();
                //遍历实体对象属性
                foreach (var info in typeof(T).GetProperties())
                {
                    object obj = null;
                    //取得object对象中此属性的值
                    var val = type.GetProperty(info.Name)?.GetValue(asObject);
                    if (val != null)
                    {
                        //非泛型
                        if (!info.PropertyType.IsGenericType)
                            obj = Convert.ChangeType(val, info.PropertyType);
                        else//泛型Nullable<>
                        {
                            Type genericTypeDefinition = info.PropertyType.GetGenericTypeDefinition();
                            if (genericTypeDefinition == typeof(Nullable<>))
                            {
                                obj = Convert.ChangeType(val, Nullable.GetUnderlyingType(info.PropertyType));
                            }
                            else
                            {
                                obj = Convert.ChangeType(val, info.PropertyType);
                            }
                        }
                        info.SetValue(t, obj, null);
                    }
                }
            }
            return t;
        }

        /// <summary>
        /// 创建客户端
        /// </summary>
        public void CerateClient()
        {
            Task.Run(() => CerateClientTask());
        }

        public static List<Socket> clientSockets = new List<Socket>();

        string[] list = { "AGV", "PLC" };


        /// <summary>
        /// 创建客户端
        /// </summary>
        public void CerateClientTask()
        {
            IPAddress ip = IPAddress.Parse(IP);  //将IP地址字符串转换成IPAddress实例
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用指定的地址簇协议、套接字类型和通信协议
            IPEndPoint endPoint = new IPEndPoint(ip, port); // 用指定的ip和端口号初始化IPEndPoint实例
            clientSocket.Connect(endPoint);  //与远程主机建立连接

            var message = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new Data { Name = list[clientSockets.Count], PackageType = "Connect" }));

            clientSocket.Send(message);

            clientSockets.Add(clientSocket);

            Task.Run(() => ReceiveMessageTask(clientSocket));
        }

        /// <summary>
        /// 接受消息
        /// </summary>
        private void ReceiveMessageTask(Socket socket)
        {
            try
            {
                while (true)
                {
                    byte[] receive = new byte[3000];
                    socket.Receive(receive);
                    var ReveiveMessage = JsonConvert.DeserializeObject<Data>(Encoding.UTF8.GetString(receive));
                    //RunLog.runLog.Debug($"【{socket.LocalEndPoint}】接收消息为：" + Encoding.UTF8.GetString(receive));

                    var task = _SqlSugarDapper.DB.Queryable<WcsTaskAGV>().ToList().First();
                    var step = Service.ServiceSocker._serviceSocker.WCSInteractiveStepList.Find(w => w.CurrentState == task.Task_State &&
                    //ReveiveMessage.SendState == w.SendState && w.InteractiveType != "Send");
                    ReveiveMessage.SendState == w.SendState && w.InteractiveType == "ReceiveInteractive");

                    if (step != null)
                    {
                        _SqlSugarDapper.DB.Updateable<WcsTaskAGV>()
                            .SetColumns(w => w.Task_State == Convert.ToInt32(step.TargetState))
                            .Where(w => w.Task_Code == ReveiveMessage.TaskCode)
                            .ExecuteCommand();

                        RunLog.runLog.Debug($"【WCS】------【{step.InteractiveDev}】接受消息为:【{step.Remarks}】更新步骤为【{task.Task_State}】 ===> 【{step.TargetState}】");
                        SendMessageTask(task.Task_Code);
                    }

                    Thread.Sleep(200);
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
            //ClientSocket.Close();  //关闭连接
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        public void SendMessage(string taskcode)
        {
            //Task.Run(() => SendMessageTask());
            SendMessageTask(taskcode);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        private void SendMessageTask(string taskcode)
        {
            byte[] message = null;

            var task = _SqlSugarDapper.DB.Queryable<WcsTaskAGV>().ToList().First();
            var step = Service.ServiceSocker._serviceSocker.WCSInteractiveStepList.Find(w => w.CurrentState == task.Task_State);

            if (step != null)
            {
                if (step.InteractiveDev == "AGV")
                {
                    var a = new Data { Name = "AGV", TaskCode = task.Task_Code, InteractiveDev = "AGV", SendState = step.SendState, PackageType = "Task" };
                    message = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(a));

                    clientSockets[0].Send(message);
                }
                else if (step.InteractiveDev == "PLC")
                {
                    var a = new Data { Name = "PLC", TaskCode = task.Task_Code, InteractiveDev = "PLC", SendState = step.SendState, PackageType = "Task" };

                    message = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(a));

                    //foreach (var item in message)
                    //{
                    //    messagesss += item.ToString("x");
                    //}
                    //var dddd = Encoding.UTF8.GetBytes(messagesss);

                    //byte[] by = new byte[messagesss.Length / 2];

                    //for (int i = 0; i < by.Length; i++)
                    //{
                    //    by[i] = Convert.ToByte(messagesss.Substring(i * 2, 2), 16);
                    //}

                    clientSockets[1].Send(message);
                }
            }
            //RunLog.runLog.Debug($"【客户端】发送消息为:" + Encoding.UTF8.GetString(message));
        }

        public void ClientSend()
        {
            ServiceSocker._serviceSocker.WCSInteractiveStepList = AGVTask._agvTask.WCSInteractiveStepList;
            byte[] message = null;

            var task = _SqlSugarDapper.DB.Queryable<WcsTaskAGV>().ToList()?.FindAll(f => f.Task_State == (int)Task_State.执行中).OrderBy(o => o.indexOrder).FirstOrDefault();
            if (task != null)
            {
                var step = ServiceSocker._serviceSocker.WCSInteractiveStepList.Find(w => w.CurrentState == task.InteractiveState && w.SendState != task.ReceiveInteractiveState &&
                w.InteractiveType != "Send");
                //w.InteractiveType == "ReceiveInteractive");

                if (step != null)
                {
                    if (ServiceSocker._serviceSocker.clientSocketConnects.Count >= 2)
                    {
                        var a = new Data { Name = "AGV", TaskCode = task.Task_Code, InteractiveDev = step.InteractiveDev, SendState = step.SendState, PackageType = "Task" };
                        message = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(a));

                        var client = ServiceSocker._serviceSocker.clientSocketConnects.Find(c => c.Name == step.InteractiveDev)?.Client;

                        if (client != null)
                        {
                            client.Send(message);
                        }
                        else
                        {
                            RunLog.runLog.Debug($"【客户端{step.InteractiveDev}】未连接");
                        }
                    }
                    else
                    {
                        var obj = new
                        {
                            station = task.Start_Station,
                            taskCode = task.Sub_TaskCode,
                            taskStatus = step.SendState,
                        };
                        var serializersettings = new JsonSerializerSettings
                        {
                            // 设置为小驼峰命名
                            ContractResolver = new CamelCasePropertyNamesContractResolver()
                        };

                        //_SqlSugarDapper.DB.Updateable<WcsTaskAGV>()
                        //    .SetColumns(w => w.ReceiveInteractiveState == step.SendState)
                        //    .Where(w => w.Sub_TaskCode == task.Sub_TaskCode)
                        //    .ExecuteCommand();

                        RunLog.runLog.Debug($"任务号【{task.Task_Code}】【{step.InteractiveDev}】发送消息为:【{step.SendState}】【{step.Remarks}】更新步骤为【{step.CurrentState}】 ===> 【{step.TargetState}】");
                        //HttpRequest.httpRequest.WebPostRequest(JsonConvert.SerializeObject(obj, serializersettings), "https://localhost:44345/AGV/ResponseTaskStatus");
                    }
                }
            }
        }
    }

    public class AGVResponseTaskStatus
    {
        /// <summary>
        /// 任务编号
        /// </summary>
        public string TaskCode { get; set; }

        /// <summary>
        /// 任务状态
        /// </summary>
        public int TaskStatus { get; set; }

        /// <summary>
        /// ：托盘号
        /// </summary>
        public string TrayCode { get; set; }
    }

    //[Serializable]
    //public class Data
    //{
    //    /// <summary>
    //    /// 设备名称
    //    /// </summary>
    //    public string Name { get; set; }

    //    /// <summary>
    //    /// 包类型
    //    /// </summary>
    //    public string PackageType { get; set; }

    //    /// <summary>
    //    /// 发送状态
    //    /// </summary>
    //    public string SendState { get; set; }

    //    /// <summary>
    //    /// 交互设备
    //    /// </summary>
    //    public string InteractiveDev { get; set; }

    //    /// <summary>
    //    /// 任务号
    //    /// </summary>
    //    public string TaskCode { get; set; }
    //}
}
